using System;
using System.Collections.Generic;
using System.Linq;
using ImageProcessing.Common;

namespace ImageProcessing.PointsSampler
{
    class LastMatchedSampler : SteppedPointsSampler, IInterestPointSampler
    {
        protected override void SelectPoints(List<InterestPoint> ipts, List<InterestPoint> lastMatchedIpts, int numberOfPointsToScan, int iptsCount)
        {
            if (lastMatchedIpts.FirstOrDefault() == null)
                base.SelectPoints(ipts, lastMatchedIpts, numberOfPointsToScan, iptsCount);
            else
            {
                var distDict = new Dictionary<double, InterestPoint>();
                var lastFoundPointsCount = lastMatchedIpts.Count;
                var pointsPerLast = numberOfPointsToScan / lastFoundPointsCount;
                foreach (var lastMatchedIpt in lastMatchedIpts)
                {

                    // now find the close point to this one
                    foreach (var interestPoint in ipts)
                    {
                        var distance = GetDistance(lastMatchedIpt, interestPoint);
                        distDict[Math.Round(distance, 3)] = interestPoint;
                    }

                    // get closest ones, link is slow and just asking for trouble
                    var closest = (from num in distDict.Values orderby distDict.Keys ascending select num).Take(pointsPerLast);
                    ProcessedIpts.AddRange(closest);

                    distDict.Clear();
                }

            }
        }

        private double GetDistance(InterestPoint lastMatchedIpt, InterestPoint interestPoint)
        {
            return Math.Sqrt(Math.Pow((lastMatchedIpt.x - interestPoint.x), 2) + Math.Pow((lastMatchedIpt.y - interestPoint.y), 2));
        }
    }
}